//
// Copyright (C) 2011 Adriano (University of Pisa)
// Copyright (C) 2012 OpenSim Ltd.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//

package inet.applications.voip;

import inet.applications.contract.IApp;

//
// Receives a VoIP stream generated by a ~SimpleVoipSender, and records statistics.
// The most important statistic is MOS (Mean Opinion Score, a value between 1
// and 5, representing a human user's view of the voice quality), computed using
// the E Model defined in the ITU-T G.107 standard. The parameters starting with
// "emodel_" correspond to the parameters of the E model.
//
// The E Model was originally developed within ETSI as a transmission planning tool,
// described in ETSI technical report ETR 250, and then standardized by the ITU as G.107.
// The objective of the model was to determine a quality rating that incorporated the
// "mouth to ear" characteristics of a speech path.
//
// The playout delay, buffer space, the UDP port to listen on, and other input
// can be specified in module parameters.
//
simple SimpleVoipReceiver like IApp
{
    parameters:
        int localPort;
        int emodelIe = default(5);        // Equipment impairment factor
        int emodelBpl = default(10);      // Packet-loss robustness factor
        int emodelA = default(5);         // Advantage factor
        double emodelRo = default(93.2);  // Basic signal-to-noise ratio

        double playoutDelay @unit(s) = default(0s);      // initial delay for beginning playout after receiving the first packet
        bool adaptivePlayoutDelay = default(false);      // if true, adjust playoutDelay after each talkspurt
        int bufferSpace = default(20);      // buffer size in packets
        double mosSpareTime @unit(s) = default(1s); // spare time before calculating MOS (after calculated playout time of last packet)

        @signal[voipPacketDelay](type="simtime_t");      // when receive a frame
        @signal[voipPacketLossRate](type="double");      // at end of talkspurt
        @signal[voipPlayoutDelay](type="simtime_t");    // at end of talkspurt
        @signal[voipPlayoutLossRate](type="double");    // at end of talkspurt
        @signal[voipMosRate](type="double");          // at end of talkspurt
        @signal[voipTaildropLossRate](type="double");   // at end of talkspurt
        @statistic[endToEndDelay](title="VoIP Packet End-to-End Delay"; unit="s"; source="voipPacketDelay"; record=stats,vector);
        @statistic[packetLossRate](title="VoIP Packet Loss"; unit="ratio"; source="voipPacketLossRate"; record=stats,vector);
        @statistic[playoutDelay](title="VoIP Playout Delay"; unit="s"; source="voipPlayoutDelay"; record=stats,vector);
        @statistic[playoutLossRate](title="VoIP Playout Loss Rate"; unit="ratio"; source="voipPlayoutLossRate"; record=stats,vector);
        @statistic[mos](title="VoIP MOS"; unit="MOS"; source="voipMosRate"; record=stats,vector);
        @statistic[taildropLossRate](title="VoIP Tail Drop Loss Rate"; unit="ratio"; source="voipTaildropLossRate"; record=stats,vector);

        @display("i=block/source");
    gates:
        input socketIn @labels(UdpControlInfo/up);
        output socketOut @labels(UdpControlInfo/down);
}

